package com.sg.common.empty.web;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.sg.common.empty.core.FilterVal;
import com.sg.common.empty.core.JspUtil3;
import com.sg.common.empty.entity.Myinput;
import com.sg.common.empty.entity.PerfProperty;
import com.sg.common.empty.entity.Property;
import com.sg.common.empty.service.CfgService;
import com.sg.common.utils.Constant;
import com.sg.common.utils.ReUtils;

public class ListDcBuilder {
	CfgService service;
	private String fg;
	private String sort;
	private String order;
	private Object bean;
	private List<PerfProperty> searchPl;
//	private Filter filter;
	private String sql;
	private String pre;

//	public static ListDcBuilder countDcBuilder(Object bean,
//			List<PerfProperty> searchPl, Filter filter, String sql, String pre) {
//		ListDcBuilder res = new ListDcBuilder();
//		res.fg = "count";
//		res.bean = bean;
//		res.searchPl = searchPl;
//		res.filter = filter;
//		res.sql = sql;
//		res.pre = pre;
//		return res;
//	}

//	public static ListDcBuilder countDcBuilder(Object bean,
//			List<PerfProperty> searchPl, Filter filter, String sql, String pre,
//			CfgService service) {
//		ListDcBuilder res = new ListDcBuilder();
//		res.fg = "count";
//		res.bean = bean;
//		res.searchPl = searchPl;
//		res.filter = filter;
//		res.sql = sql;
//		res.pre = pre;
//		res.service = service;
//		return res;
//	}

//	public static ListDcBuilder listDcBuilder(String sort, String order,
//			Object bean, List<PerfProperty> searchPl, Filter filter,
//			String sql, String pre) {
//		ListDcBuilder res = new ListDcBuilder();
//		res.sort = sort;
//		res.order = order;
//		res.bean = bean;
//		res.searchPl = searchPl;
//		res.filter = filter;
//		res.sql = sql;
//		res.pre = pre;
//		return res;
//	}

//	public static ListDcBuilder listDcBuilder(String sort, String order,
//			Object bean, List<PerfProperty> searchPl, Filter filter,
//			String sql, String pre, CfgService service) {
//		ListDcBuilder res = new ListDcBuilder();
//		res.sort = sort;
//		res.order = order;
//		res.bean = bean;
//		res.searchPl = searchPl;
//		res.filter = filter;
//		res.sql = sql;
//		res.pre = pre;
//		res.service = service;
//		return res;
//	}
//
//	public DetachedCriteria buildDc() throws SecurityException,
//			IllegalArgumentException, NoSuchFieldException,
//			ClassNotFoundException, IllegalAccessException,
//			InvocationTargetException, NoSuchMethodException,
//			InstantiationException {
//		if (!"count".equals(fg)) {
//			if (StringUtils.isEmpty(sort)) {// 为空才需要设置默认的排序，非空则按非空要求进行排序
//				if (ReUtils.findField(bean, "ord") != null) {
//					sort = "ord";
//					order = "asc";
//				} else {
//					sort = "id";
//					order = "desc";
//				}
//			}
//		}
//		DetachedCriteria dc = createRectiDc();
//		Field enableField = ReUtils.findField(bean, "enable");
//		if (enableField != null) {
//			dc.add(Restrictions.ne(enableField.getName(), Constant.ENABLE_DEL));
//		}
//		// service.createFilterDc(dc, filter);
//		if (filter != null
//				&& StringUtils.equalsIgnoreCase("sql", filter.getType())) {
//			String func = dealfunc(filter.getFunc());
//			if (StringUtils.isNotEmpty(func))
//				dc.add(Restrictions.sqlRestriction(func));// TODO,统一考虑
//		}
//		if (StringUtils.isNotEmpty(sql)) {
//			dc.add(Restrictions.sqlRestriction(sql));
//		}
//		if (StringUtils.isNotEmpty(pre)) {
//			dc.add(Restrictions.sqlRestriction(pre));
//		}
//		return dc;
//	}

	private String dealfunc(String func) {
		String res = func;
		if (StringUtils.isNotEmpty(func)) {
			List<String> funcs = new ArrayList<String>();

			while (func.indexOf("%%{") > 0) {
				int begin = func.indexOf("%%{");
				String right = func.substring(begin + 3);
				int end = right.indexOf("}");
				String para = right.substring(0, end);
				func = right;
				funcs.add(para);
			}
			for (String f : funcs) {
				String filtervalue = FilterVal.init(f, service).get()
						.toString();
				if (StringUtils.isNotEmpty(filtervalue)) {
					String tar = "%%{" + f + "}";
					res = res.replace(tar, filtervalue);
				} else
					res = "";
			}
		}
		return res;
	}

	/**
	 * 自带搜索条件的dc创建方法
	 * 
	 * @param sort
	 * @param orderx
	 * @param bean
	 * @param className
	 * @return
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws InstantiationException
	 */
	public DetachedCriteria createRectiDc2() throws SecurityException,
			NoSuchFieldException, ClassNotFoundException,
			IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, NoSuchMethodException,
			InstantiationException {
		List<String> sl = new ArrayList<String>();// 用于检测是否会发生duplicate alias错误
		DetachedCriteria dc;
		// ===================================dym
		if (bean instanceof Map) {
			dc = DetachedCriteria.forEntityName(ReUtils.getStr(bean,
					Constant.BEAN_TYPE));
		}
		// ===================================dym
		else {
			Class<?> clazz = bean.getClass();
			dc = DetachedCriteria.forClass(clazz);
		}
		if (StringUtils.isNotEmpty(sort) && !sort.contains(".")) {// !sort.contains(".")
																	// ：在包含点号时，无法用其进行排序
			if ("desc".equals(order)) {
				dc.addOrder(Order.desc(sort));
			} else {
				dc.addOrder(Order.asc(sort));
			}
			dc.addOrder(Order.asc("id"));
		}
		// data filter

		if (bean != null) {
			String beanValue = "";
			for (PerfProperty pp : searchPl) {
				Property property = pp.getProperty();
				String field = property.getProperty();
				if (StringUtils.isNotEmpty(property.getVotype())) {// 对于类搜索，类的id作为搜索条件
					field += ".id";
				}
				beanValue = ReUtils.getStr(bean, field);
				int indexOf = field.indexOf(".");
				Class<?> type;
				// ===================================dym
				// if (bean instanceof Map) {
				// type = ReUtils.mapType(bean, field);
				// }
				// //===================================dym
				// else {
				type = ReUtils.type(bean, field);
				// }
				// String child = "";
				// if (indexOf >= 0) {
				// child = field.substring(indexOf + 1, field.length());
				// f1 = field.substring(0, indexOf);
				// Field declaredField = clazz.getDeclaredField(f1);
				// Class<?> f1type = declaredField.getType();
				// BaseTO mem = (BaseTO) declaredField.get(bean);
				// if (mem != null) {
				// Field childField = f1type.getDeclaredField(child);
				// type = childField.getType();
				// beanValue = String.valueOf(childField.get(mem));
				// }
				// } else {
				// Field declaredField = clazz.getDeclaredField(field);
				// type = declaredField.getType();
				// beanValue = String.valueOf(declaredField.get(bean));
				// }
				if (StringUtils.isNotEmpty(beanValue)) {
					String s1 = beanValue.substring(1);
					if (beanValue.startsWith("=")) {
						dc.add(Restrictions.eq(field, s1));
					} else if (beanValue.startsWith(">")) {
						dc.add(Restrictions.gt(field, s1));
					} else if (beanValue.startsWith(">=")) {
						dc.add(Restrictions.ge(field, beanValue.substring(2)));
					} else if (beanValue.startsWith("<")) {
						dc.add(Restrictions.lt(field, s1));
					} else if (beanValue.startsWith("<=")) {
						dc.add(Restrictions.le(field, beanValue.substring(2)));
					} else if (beanValue.startsWith("%")) {
						dc.add(Restrictions.ilike(field, s1, MatchMode.END));
					} else if (beanValue.endsWith("%")) {
						dc.add(Restrictions.ilike(field,
								beanValue.substring(0, beanValue.length() - 1),
								MatchMode.START));
					} else {
						if (type != null) {
							if (type.equals(int.class)) {
								Integer valueOf = Integer.valueOf(beanValue);
								if (indexOf >= 0 && valueOf == 0) {
									// TODO 如果是donothing
								} else {
									dc.add(Restrictions.eq(field, valueOf));
								}
							} else {
								Myinput input = JspUtil3.propertyMyinput(pp);
								if (input != null
										&& input.getType().endsWith("date")) {
									// 对date进行情况判断
									if (beanValue.contains(" - ")) {
										// 时间阶段统计
										String[] ds = beanValue.split(" - ");
										dc.add(Restrictions.ge(field, ds[0]))
												.add(Restrictions.le(field,
														ds[1] + " 23:59:59"));
									} else {
										// 单天时间
										dc.add(Restrictions
												.ge(field, beanValue)).add(
												Restrictions
														.le(field, beanValue
																+ " 23:59:59"));
									}
								} else if (input != null
										&& (input.getType().equals("select") || input
												.getType().equals("tree"))) {
									dc.add(Restrictions.eq(field, beanValue));

								} else {
									if (indexOf > 0) {
										String f1 = field.substring(0, indexOf);
										if (!sl.contains(f1)) {
											dc.createAlias(f1, f1);
											sl.add(f1);
										}

									}
									dc.add(Restrictions.ilike(field, beanValue,
											MatchMode.ANYWHERE));
								}
							}
						}
					}
				}
			}
		}
		return dc;
	}

	/**
	 * 自带搜索条件的dc创建方法
	 * 
	 * @param sort
	 * @param orderx
	 * @param bean
	 * @param className
	 * @return
	 * @throws NoSuchMethodException
	 * @throws InvocationTargetException
	 * @throws InstantiationException
	 */
	public DetachedCriteria createRectiDc() throws SecurityException,
			NoSuchFieldException, ClassNotFoundException,
			IllegalArgumentException, IllegalAccessException,
			InvocationTargetException, NoSuchMethodException,
			InstantiationException {
		List<String> sl = new ArrayList<String>();// 用于检测是否会发生duplicate alias错误
		DetachedCriteria dc;
		// ===================================dym
		if (bean instanceof Map) {
			dc = DetachedCriteria.forEntityName(ReUtils.getStr(bean,
					Constant.BEAN_TYPE));
		}
		// ===================================dym
		else {
			Class<?> clazz = bean.getClass();
			dc = DetachedCriteria.forClass(clazz);
		}
		if (StringUtils.isNotEmpty(sort) && !sort.contains(".")) {// !sort.contains(".")
																	// ：在包含点号时，无法用其进行排序
			if ("desc".equals(order)) {
				dc.addOrder(Order.desc(sort));
			} else {
				dc.addOrder(Order.asc(sort));
			}
			// dc.addOrder(Order.asc("id"));
		}
		// data filter

		if (bean != null) {
			String beanValue = "";
			for (PerfProperty pp : searchPl) {
				Property property = pp.getProperty();
				String field = property.getProperty();
				if (StringUtils.isNotEmpty(property.getVotype())) {// 对于类搜索，类的id作为搜索条件
					field += ".id";
				}
				beanValue = ReUtils.getStr(bean, field);
				int indexOf = field.indexOf(".");
				if (StringUtils.isNotEmpty(beanValue)) {
					Myinput input = JspUtil3.propertyMyinput(pp);

					if (input != null) {
						if (indexOf > 0) {
							String f1 = field.substring(0, indexOf);
							if (!sl.contains(f1)) {
								dc.createAlias(f1, f1);
								sl.add(f1);
							}

						}
						String inputType = input.getType();
						if (StringUtils.equals(inputType, "text")
								|| StringUtils.equals(inputType, "textarea")) {
							String s1 = beanValue.substring(1);
							if (beanValue.startsWith("=")) {
								dc.add(Restrictions.eq(field, s1));
							} else if (beanValue.startsWith(">")) {
								dc.add(Restrictions.gt(field, s1));
							} else if (beanValue.startsWith(">=")) {
								dc.add(Restrictions.ge(field,
										beanValue.substring(2)));
							} else if (beanValue.startsWith("<")) {
								dc.add(Restrictions.lt(field, s1));
							} else if (beanValue.startsWith("<=")) {
								dc.add(Restrictions.le(field,
										beanValue.substring(2)));
							} else if (beanValue.startsWith("%")) {
								dc.add(Restrictions.ilike(field, s1,
										MatchMode.END));
							} else if (beanValue.endsWith("%")) {
								dc.add(Restrictions.ilike(
										field,
										beanValue.substring(0,
												beanValue.length() - 1),
										MatchMode.START));
							} else {
								dc.add(Restrictions.ilike(field, beanValue,
										MatchMode.ANYWHERE));
							}
						} else if (StringUtils.endsWith(inputType, "date")) {
							// 对date进行情况判断
							if (beanValue.contains(" - ")) {
								// 时间阶段统计
								String[] ds = beanValue.split(" - ");
								dc.add(Restrictions.ge(field, ds[0])).add(
										Restrictions.le(field, ds[1]
												+ " 23:59:59"));
							} else {
								// 单天时间
								dc.add(Restrictions.ge(field, beanValue)).add(
										Restrictions.le(field, beanValue
												+ " 23:59:59"));
							}
						} else {
							dc.add(Restrictions.eq(field, beanValue));

						}
					}
				}

			}
		}
		return dc;
	}
}
